using UnityEngine;
using System.Collections;

public class VolumetricLight : MonoBehaviour {


    const int LayersToIgnore = (1 <<8) + (1<<14) + (1<<10);
    public Material material;

    [HideInInspector]
    public int rayAmount = 30;

    Vector3[] vertices;
    Mesh mesh;
    
    /// <summary>
    /// Crea el mesh inicial.
    /// </summary>
    /// <param name="rays">Cantidad de rayos, mas rayos equivale a mas detalle
    /// pero menos performance.</param>
    public void CreateMesh(int rays)
    {
        if (rays <= 1) return;
        rayAmount = rays;
        MeshFilter filter = this.gameObject.AddComponent<MeshFilter>();
        mesh = new Mesh();
        vertices = new Vector3[rayAmount + 1];

        mesh.vertices = vertices;

        int[] indices = new int[(rayAmount - 1) * 3];

        int j = 0;
        for (int i = 0; i < indices.Length; i += 3)
        {
            indices[i] = 0;
            indices[i + 1] = j + 1;
            indices[i + 2] = j + 2;
            j++;
        }

        mesh.SetIndices(indices, MeshTopology.Triangles, 0);

        filter.sharedMesh = mesh;

        MeshRenderer renderer = this.gameObject.AddComponent<MeshRenderer>();

        renderer.sharedMaterial = material;

        Vector2[] uv = new Vector2[vertices.Length];
        Vector3[] normales = new Vector3[vertices.Length];
        mesh.uv = uv;
        mesh.normals = normales;
    }
    /// <summary>
    /// Actualiza la posicion de los vertices.
    /// </summary>
    /// <param name="position">Posicion de donde sale la luz</param>
    /// <param name="eyeDirection">Direccion</param>
    /// <param name="angle">Angulo del cono</param>
    /// <param name="range">Rango del cono</param>
    /// <param name="rotationAxis">Eje perpendicular a la luz.</param>
    public void UpdateVertices(Vector3 position, Vector3 eyeDirection, float angle, float range, Vector3 rotationAxis)
    {
        vertices[0] = position;
        eyeDirection.Normalize();
        float initialAngle = -(angle / 2.0f);
        float anglePerRay = angle / (float)(rayAmount - 1);
        for (int i = 0; i < rayAmount; i++)
        {
            //angulo al que roto la direccion del ojo para este rayo.
            float rayAngle = initialAngle + anglePerRay * i;

            Vector3 rayDirection = Quaternion.AngleAxis(rayAngle, rotationAxis) * eyeDirection;
            rayDirection.y = 0;
            Ray ray = new Ray(position, rayDirection);
            RaycastHit hitInfo;
            if (Physics.Raycast(ray, out hitInfo, range,~(LayersToIgnore)))
            {
                vertices[i + 1] = hitInfo.point;
            }
            else
            {
                vertices[i + 1] = position + rayDirection.normalized * range;
            }
        }
        mesh.vertices = vertices;
        mesh.RecalculateBounds();
        //Debug.Log(position+" , "+ eyeDirection+" , "+angle+" , "+range);
    }
}
